﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using System.Net;

namespace TheLoader.classes
{
    public class TheLoaderTestEventArgs
    {


        private DateTime _StartTime;
        private DateTime _EndTime;
        private double _Duration;
        private string _URL;
        

        public DateTime StartTime { get { return _StartTime; } }
        public DateTime EndTime { get { return _EndTime; } }
        public double Duration { get { return _Duration; } }
        public string URL { get { return _URL; } }
        public string ID { get; set; }
        public int CurrentLine { get; set; }
        public int TotalLines { get; set; }
        public double TotalTestTime { get; set; }
        public string CurrentPageHtml { get; set; }
        public int NumberofRuns { get; set; }
        public int NumberofURLs { get; set; }
        public TheLoaderTest CurrentTest { get; set; }
        public double AveragePageTime
        {
            get
            {
                double dAvg = Math.Round(TotalTestTime / NumberofURLs, 2);
                return dAvg;
            }
        }


        internal void SetStartTime()
        {
            _StartTime = DateTime.Now;
        }

        internal void SetEndTime()
        {
            _EndTime = DateTime.Now;
        }

        internal void SetDurationTime(double duration)
        {
            _Duration = Math.Round(duration, 2);
        }

        internal void SetURL(string url)
        {
            _URL = url;
        }


    }


    public class TheLoaderTest
    {
        public delegate void BrowseStartEventHandler(TheLoaderTestEventArgs e);
        public delegate void BrowseEndEventHandler(TheLoaderTestEventArgs e);
        public delegate void TestStartEventHandler(TheLoaderTestEventArgs e);
        public delegate void TestEndEventHandler(TheLoaderTestEventArgs e);

        public event BrowseStartEventHandler BrowseStarted;
        public event BrowseEndEventHandler BrowseEnded;
        public event TestStartEventHandler TestStarted;
        public event TestEndEventHandler TestEnded;

        PerformanceTimer pt;

        private bool _IsRunning;

        public bool TimeResponseOnly { get; set; }
        public string currentUrl { get; set; }
        public string TestID { get; set; }
        public double LastLoadTime { get; set; }
        public string FileName { get; set; }
        public bool IsRunning { get { return _IsRunning; } }
        
        
        public List<string> URLs = new List<string>();
        
        
        int currentLine = 0;
       public  TheLoaderTestEventArgs bge = new TheLoaderTestEventArgs();

        public void FetchPage()
        {
            currentUrl = URLs[currentLine];
            bge.CurrentLine = currentLine + 1;
            pt = new PerformanceTimer();
            pt.Start();
            //bge.SetStartTime();
            bge.SetURL(currentUrl);
            StringBuilder sb = new StringBuilder();

            // used on each read operation
            byte[] buf = new byte[8192];

            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest)
                WebRequest.Create(currentUrl);
            if (this.BrowseStarted != null)
                this.BrowseStarted(bge);

            // execute the request
            HttpWebResponse response = (HttpWebResponse)
                request.GetResponse();


            if (!TimeResponseOnly)
            {
                // we will read data via the response stream
                Stream resStream = response.GetResponseStream();
                string tempString = null;
                int count = 0;

                do
                {
                    // fill the buffer with data
                    count = resStream.Read(buf, 0, buf.Length);

                    // make sure we read some data
                    if (count != 0)
                    {
                        // translate from bytes to ASCII text
                        tempString = Encoding.ASCII.GetString(buf, 0, count);

                        // continue building the string
                        sb.Append(tempString);
                    }
                }
                while (count > 0); // any more data to read?
                bge.CurrentPageHtml = tempString;
            }
            else
            {
                response.Close();
            }

            pt.Stop();
            //this.bge.SetEndTime();
            this.bge.NumberofURLs += 1;
            this.bge.SetDurationTime(pt.Duration);
            this.bge.TotalTestTime += pt.Duration;
            if (this.BrowseEnded != null)
                this.BrowseEnded(this.bge);


        }

        public void StartRun()
        {

            
            this.bge.ID = this.TestID;
            this.bge.CurrentTest = this;
            //this.bge.SetStartTime();
            if (this.TestStarted != null)
                this.TestStarted(bge);
            _IsRunning = true;
            DoAllPages();


        }

        private void DoAllPages()
        {
            
            
                currentLine = 0;
                foreach (string s in URLs)
                {
                    if (s != "")
                    {
                        FetchPage();
                        currentLine++;
                    }
                }
                
                
                //this.bge.SetEndTime();
                if (this.TestEnded != null)
                    this.TestEnded(bge);

                _IsRunning = false;
                


        }

       

    }
}
